<?php

namespace app\datacollect\controller;

use app\common\lib\SensorsData;
use app\datacollect\common\DataToFile;
use Exception;
use think\Log;
use think\response\Json;
use XznsTools\cache\CacheManage;

class Sink extends DataCollectAuth
{

    private static $LOG_PRE = '数据分析平台-日志采集：';

    /**
     * 接收埋点数据
     * 测试接口：https://local-beta-wechat.goddessxzns.com/datacollect/sink?project=zhunle_beta&token=skad6m37nor5qvyc
     */
    public function sink()
    {

//        curl 请求：
//curl - H "Host: local-beta-wechat.goddessxzns.com" - H "Cookie: SERVER_ID=vserver-0opkwyan-backend-15kb5slc" - H "Accept: */*" - H "User-Agent: SensorsAnalytics iOS SDK" - H "Accept-Language: zh-cn"--data "crc=-603048877&gzip=1&data_list=H4sIAAAAAAAAE%2BVU0W7bIBT9F9RH2wKMCc6buyZTn1Ypk%2FYwTci1cYxqgwU4WVr13weJ26RVs%2FVh0qbNb75czrn3nnv4%2BgA6vZaKyxrMgRLb6xpEwMlegDmiM0hnJGUQz2gESqXVrtejPeQWCwQRQct4tsAoJpQWcYEIiT%2FAnGJG6eKygB5KbIRyPv2iGIaFCuDcmbK624OQPGV5xiiLgKx9nnRSWDB%2FABfT746%2FUd3xUNbNxh%2FkebFgsxzGWUFxTPJLEhfLJYuLnGVXmCJ0uSDgMQKD0YMwTxycFzc3K1c6wTmYY4%2BrfRzIT6vAUQ4D3whjpVY%2BiBKSoBC2lRFC8a2sXQvmKYYRKIrivTWE2i1vpLGO1%2BUOzJ0ZhQ%2F2uhZd4L5ptRIIRyyk1mIjK3Ho%2Fb3wSritNnfc7QavIPhyvbwO4SDovYfmumms8HrEhMGpS1UGscFKKKuNvSpdGW5sZSOf61sLzSutTS1VGJfdWSf6AP9xxcjJWFoh161Hz4KiF13pRRprD57meY4wJCEob3kvXKtDV%2BXo9OewDQGj02o95SNEGSIpJdP%2B8Ho0HixIwXBKEkwxnD601%2B1UKpJQcCA6qtmXamzKyo1GmLC7w9CJKenkKkmyBJ60o4305BMxGLTxmyvd03bsdal0n3RybEXy%2FV7ZsGR73oez0C%2FKOrNkZ2bkwWtpnVSVe2XXg9humiRvutG2%2FGhiP7MM5oiix%2BgXdp8yM%2Fw77O69ZdxLw6M0zXLGMIV%2F3vHwv3S8EXbsBW%2BM7vmtl2Vt9Oif5ae6%2Fv4H4ZyxfmLxo8ZvvhTPAh180JSdFf%2FyI%2FDtB7e2u431BwAA"--compressed "https://local-beta-wechat.goddessxzns.com/datacollect/sink?project=zhunle_beta&token=skad6m37nor5qvyc"


        $crc = input('crc/d');//data_list->压缩、加密后的 hashCode值 todo 不知道是干啥用的
        $gzip = input('gzip/d', 1);//1=> 未手动加密 9 => 经做过 gzip 压缩和 base64 处理了 todo 不知道是干啥用的
        $data_list = input('data_list/s', '');//app端 加密的数据
        $data = input('data/s', '');//js端 加密的数据
        $method = $this->request->method();
        if ($method === 'GET')
        {
            $is_js = true;
        } else
        {
            $is_js = false;
        }

        //传入参数检查
        if (empty($data_list) && empty($data))
        {
            Log::write(self::$LOG_PRE . 'data_list和data，不能为空！', 'error', true);
            return show(0, '参数异常');
        }
        //todo 检查 crc 和 gzip

        $result = [];
        try
        {
            //神策，在线解码工具：https://www.sensorsdata.cn/tools/decode.html
            //JS 端数据解码顺序：UrlDecode 解码 —> Base64 解码。
            //App 端数据解码顺序：UrlDecode 解码 —> Base64 解码 —> Gzip 解压。

            if (!$is_js && !empty($data_list))
            {//app 埋点数据
                $data_base64_decode = base64_decode($data_list);
                if (function_exists('gzdecode'))
                {
                    $result = gzdecode($data_base64_decode);
                } else
                {
                    Log::write(self::$LOG_PRE . 'gzdecode方法不存在，App打点失败！', 'error', true);
                }
                //写入日志
                DataToFile::getInstance()->writeToFile(json_decode($result), false);
            } else if ($is_js && !empty($data))
            {//js 埋点数据
                $result = base64_decode($data);
                //写入日志
                DataToFile::getInstance()->writeToFile($result, true);
            } else
            {
                Log::write(self::$LOG_PRE . '请求参数异常，既不是app打点也不是js打点', 'error', true);
                return null;
            }


            //test
//            Log::write(self::$LOG_PRE . '打点类型=' . (!$is_js ? 'app' : 'js') . ',解码结果=' . $result, 'log', true);
            //test 神策的track，写日志方法
//            SensorsData::track('12345883', true, 'test', ['a' => 'a', 'b' => 'b']);
        }
        catch (Exception $e)
        {
            Log::write(self::$LOG_PRE . '处理异常，message=' . $e->getMessage() . ',file=' . $e->getFile() . ',line=' . $e->getLine() . '，失败行数：' . $e->getLine(), 'error');
        }
    }


    /**
     * 接收debug数据
     * 原理：接收的参数，解密一下，然后放入到redis里，在go的后台进行读取；
     * 测试接口：https://local-beta-wechat.goddessxzns.com/datacollect/debug?project=zhunle_beta&token=skad6m37nor5qvyc
     * @return Json
     */
    public function debug(): Json
    {
        //第一次curl请求：
//        curl -H 'Host: local-beta-wechat.goddessxzns.com' -H 'Content-Type: text/plain' -H 'Accept: */*' -H 'User-Agent: SensorsData/1 CFNetwork/1240.0.4 Darwin/20.5.0' -H 'Accept-Language: zh-cn' --data-binary '{"distinct_id":"AE10141F-7E21-466A-A144-C0962866EBA0"}' --compressed 'https://local-beta-wechat.goddessxzns.com/datacollect/debug?project=zhunle_beta&token=skad6m37nor5qvyc&info_id=debugmode2164&project=zhunle_beta&url=http%253A%252F%252F192.168.0.193%253A9999%252Fbase%252FstartDataDebugSchemeUrl%253Fprject%253Ddefault&pairing_code=2164'

        //上传数据curl 请求：
//        curl -H 'Host: local-beta-wechat.goddessxzns.com' -H 'Dry-Run: true' -H 'Accept: */*' -H 'User-Agent: SensorsAnalytics iOS SDK' -H 'Accept-Language: zh-cn' --data "crc=1016382472&gzip=1&data_list=H4sIAAAAAAAAE51Ua2vbMBT9K0Xrx9hY8TvfnMQphcHK0q2MMYxqX8eitmQkOWlW%2Bt935bptRtkzEIKkc%2B7j3HPz9YEwIcWxk4MueEUWJMupRwO6ceJ8Tp0gijIno0HgrLw0midRlC8zj8xIYRQr70YKDUI%2FnYfJjMAehMEY51nff%2BZw2JYKQCDa8A4QGMVemoYRxW84I7xCNDccNFk8kPPpeCz%2Br6BXPq%2FqPfLiTRbO%2FXXseOkqd4IsWDtJOs%2BcKKFJmEdhHMSUPM5Iy2%2FH%2FPhbVGAYb5G8hk6upDBKti2od%2BPHJrGgPSjNpUBU4IauN13jkX%2FY2gPr%2BxMMdQOXPlM7MI20TbHByGuroK2gV7IH9SKE1Kf0wI0sW%2Bo%2FJtCj2sWBV6YhCz9Gic9RkBaVJ1sQWiqdCdYeDS%2F1GYY6s00iMcuyv5XLyqyLmittioodycKoAfCykxVY2fhVIwXQ%2BSyx0Ar2vISnKa4S39ssU9%2BheR47wdpfOknupQ7FrFmSeHSZjuEFmINUd4U59rbum8vNJRn76OA7hi5kXWtAjzlB4s2IboZ7LnYIvGA79qyNYN1Jz2tmxpcDr%2FlLwTuQRSmlqrhgBgp91AY6m%2B9imwQWPSjbz43cNvwLv4BPH9%2BfSNwA3zVYRBTFdrAMVR4qTOmnaUp9f46XCmpQChQGuQZtrtltC3YlXk31G0%2FYFyl2U1RKcQaB70WvBUwd%2FuzSN0bsmBhqVprhqQ5cSvTCr008xZaK4yJhT%2BNrLxVuOjd25Yvs6mprrF4FWXiT2ON0S9m5LR8acO%2B%2FC209XXFtuCjNP%2B3wNHQziVDU7aCb4s2fR%2BI%2FfvsBl5GdnLkEAAA%3D" --compressed 'https://local-beta-wechat.goddessxzns.com/datacollect/debug?project=zhunle_beta&token=skad6m37nor5qvyc'


        $pairing_code = input('pairing_code/d', 0);//debug实时日志，code码【ios传了，android没有传】
        $info_id = input('info_id/s', '');//debug实时日志【IOS：debugmode8359 Android：debugmode8359】

        // 获取redis操作对象
        $redis = CacheManage::getInstance()->redisHandler;

        if ($pairing_code !== 0 || $info_id !== '')
        {//第一次请求，已扫码的 distinct_id
            if ($pairing_code === 0)
            {//android这里只传了 info_id，把 $pairing_code 解析出来
                $pairing_code = substr($info_id, -4);
            }
            $input = file_get_contents("php://input");
            if (!empty($input))
            {
                $input_arr = json_decode($input, true);
                if (isset($input_arr['distinct_id']))
                {
                    //告诉gva已经扫码的 distinct_id
                    $redis->set('data_collect:debug:qr_status_pre:' . $pairing_code, 2, 3600);
                    $redis->set('data_collect:debug:open_app_id:' . $pairing_code, $input_arr['distinct_id'], 3600);
                    return show(config('code.error'), '获取 distinct_id 成功！');
                }
            }

            Log::write(self::$LOG_PRE . 'debug模式第一次请求：input=' . $input . ',pairing_code=' . $pairing_code, 'error', true);
            return show(config('code.error'), '获取 distinct_id 失败，input内容为空');

        } else
        {//debug上传数据

            $crc = input('crc/d');//data_list->压缩、加密后的 hashCode值
            $gzip = input('gzip/d', 1);//1=> 未手动加密 9 => 经做过 gzip 压缩和 base64 处理了
            $data_list = input('data_list/s', '');//app端 加密的数据
            $data = input('data/s', '');//js端 加密的数据

            //传入参数检查
            if (empty($data_list) && empty($data))
            {
                Log::write(self::$LOG_PRE . 'data_list和data，不能为空！', 'error', true);
                return show(0, '参数异常');
            }
            //todo 检查 crc 和 gzip

            $result = [];
            try
            {
                //神策，在线解码工具：https://www.sensorsdata.cn/tools/decode.html
                //JS 端数据解码顺序：UrlDecode 解码 —> Base64 解码。
                //App 端数据解码顺序：UrlDecode 解码 —> Base64 解码 —> Gzip 解压。
                $data_base64_decode = base64_decode($data_list);

                if (!empty($data_list))
                {//app 埋点数据
                    if (function_exists('gzdecode'))
                    {
                        $result = gzdecode($data_base64_decode);
                    } else
                    {
                        Log::write(self::$LOG_PRE . 'gzdecode方法不存在', 'error', true);
                    }
                } else
                {//js 埋点数据
                    $result = $data_base64_decode;
                }

                //消息写到redis里
                $len = 20;//最大保留20个
                $msg_arr = json_decode($result, true);
                foreach ($msg_arr as $v)
                {
                    $last = $v['anonymous_id'];
                    if (isset($v['login_id']))
                    {
                        $last = $v['login_id'];
                    }
                    $cacheKey = 'data_collect:debug:' . $last;
                    $num = $redis->lLen($cacheKey);
                    if ($num >= $len)
                    {
                        $redis->rPop($cacheKey);
                    }
                    $record = json_encode($v);
                    $redis->lPush($cacheKey, $record);
                    $redis->expire($cacheKey, 3600); // 缓存1小时过期时间
                }

                return show(config('code.success'), 'ok');
            }
            catch (Exception $e)
            {
                Log::write(self::$LOG_PRE . 'debug实时日志，处理异常，' . $e->getMessage() . '，失败行数：' . $e->getLine(), 'error');
            }
        }

    }

}
